package com.wzy.media.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wzy.media.mapper.MediaFilesMapper;
import com.wzy.media.mapper.MediaProcessHistoryMapper;
import com.wzy.media.mapper.MediaProcessMapper;
import com.wzy.media.model.po.MediaFiles;
import com.wzy.media.model.po.MediaProcess;
import com.wzy.media.model.po.MediaProcessHistory;
import com.wzy.media.service.MediaFileProcessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author wzy
 * @Date 2024/1/15 16:47
 * @description: 视频任务处理实现类
 */

@Slf4j
@Service
public class MediaFileProcessServiceImpl implements MediaFileProcessService {
    @Autowired
    private MediaProcessMapper mediaProcessMapper;
    @Autowired
    private MediaFilesMapper mediaFilesMapper;
    @Autowired
    private MediaProcessHistoryMapper mediaProcessHistoryMapper;

    /**
     * 以任务（视频）序号按取模的方式分派给各个执行器处理
     * @param shardTotal  执行器总数
     * @param shardIndex  任务序号
     * @param count 任务数
     * @return
     */
    @Override
    public List<MediaProcess> selectListByShardIndex(int shardTotal, int shardIndex, int count) {
        List<MediaProcess> mediaProcesses = mediaProcessMapper.selectListByShardIndex(shardTotal, shardIndex, count);
        return mediaProcesses;
    }

    /**
     * 开启一个任务
     * @param mediaProcess 待处理任务
     * @return true开启任务成功，false开启任务失败
     */
    @Override
    public Boolean startTask(MediaProcess mediaProcess) {
        int i = mediaProcessMapper.startTask(mediaProcess.getId());
        if(i<=0){
            return false;
        }else{
            //开启任务成功 将任务开始时间插入数据库
            LambdaUpdateWrapper<MediaProcess> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MediaProcess::getId,mediaProcess.getId()).set(MediaProcess::getBeginDate,LocalDateTime.now());
            mediaProcessMapper.update(null,updateWrapper);
            return true;
        }
    }

    /**
     * 保存处理任务结果
     * @param taskId 任务id
     * @param status 任务状态 状态,1:未处理，2：处理成功  3处理失败 4处理中
     * @param fileId 视频文件id
     * @param url   视频文件链接
     * @param errorMsg  处理失败信息
     */
    @Transactional
    @Override
    public void saveProcessFinishStatus(Long taskId, String status, String fileId, String url, String errorMsg) {
        //查出任务 如果不存在则直接返回
        MediaProcess mediaProcess = mediaProcessMapper.selectById(taskId);
        if(mediaProcess==null){
            return;
        }
        //如果任务处理失败
        if(status.equals("3")){ //处理失败
            mediaProcess.setStatus("3");//状态修改为处理失败
            mediaProcess.setFailCount(mediaProcess.getFailCount()+1);//失败次数加1
            mediaProcess.setErrormsg(errorMsg);//失败信息
            mediaProcessMapper.updateById(mediaProcess);
            log.debug("更新任务处理状态为失败，任务信息:{}",mediaProcess);
            return ;
        }
        //如果任务处理成功
        mediaProcess.setStatus("2");//状态修改为处理成功
        //1.更新media_file表中的url
        MediaFiles mediaFiles = mediaFilesMapper.selectById(fileId);
        if(mediaFiles!=null){
            //更新url
            mediaFiles.setUrl(url);
            mediaFilesMapper.updateById(mediaFiles);
        }
        //2.将处理成功记录插入media_process_history 历史记录表
        MediaProcessHistory mediaProcessHistory = new MediaProcessHistory();
        BeanUtils.copyProperties(mediaProcess,mediaProcessHistory);
        mediaProcessHistory.setFinishDate(LocalDateTime.now());
        mediaProcessHistory.setUrl(url);
        mediaProcessHistoryMapper.insert(mediaProcessHistory);
        //3.从media_process中删除该记录
        mediaProcessMapper.deleteById(taskId);
    }

    /**
     * 当处理时间超过最大时间判定为失败则修改任务状态
     * @param maxTime 最大时间
     * @return
     */
    @Override
    public Boolean updateStatusExceedMaxTime(int maxTime) {
        int i = mediaProcessMapper.updateStatusExceedMaxTime(maxTime);
        log.debug("开始修改");
        return i > 0;
    }
}

















